<!DOCTYPE html>
<html class='objectContainer'>
	<head>
		<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
		<title>■</title>
		<link rel="stylesheet" href="stylesheets/stylesheet.css">
		<!-- <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
		<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> -->
		<!-- <script src='Queue.js'></script> -->
		<script src="angular.min.js"></script>
	</head>
	<body ng-app="myApp" ng-controller="myCtrl" class='objectContainer' style='position:absolute;height:100%;background-color:black;'>
		<div id='fps' style='position:absolute;font-size:14px;color:grey;top:1px;right:1px;'>{{fps}}</div>
		<div id='theGrid' style='margin-left:20%;margin-top:5px;position:absolute;'></div>
		<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 200 200" version="1.1" style='position:absolute;right:30px;'>
		    <polygon id='startStop' ng-mouseover='hoveredStartStopButton(true)' ng-mouseout='hoveredStartStopButton(false)' ng-click='toggleStartStop()' style="fill:#841414;stroke:grey;stroke-width:8px;font-size:10px;" points="136.737609507049,188.692435121084 63.2623904929514,188.692435121084 11.3075648789165,136.737609507049 11.3075648789165,63.2623904929514 63.2623904929513,11.3075648789165 136.737609507049,11.3075648789165 188.692435121084,63.2623904929513 188.692435121084,136.737609507049"/>
		</svg>
	</body>
</html>

<script>
//the answer to "how to i access scope variables from console"
//angular.element($0).scope()

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $interval, $compile) {
	
	//----------------Declarations------------------ AKA vars that need a start but no default, ang or not.
	$scope.progress = []
	timeList = [];
	var timer =  totalTicks = 0;
	var multFromFps  =1
	stop=0 //type stop=1 in console to pause the game. If you do it often, put a button on the action or make it hotkeyed to the 'space' key. (example in manualactions.js)
	currentIndexOfDepth = [0, 0, 0, 0, 0, 0, 0]
	var fadeReduction = 0;
	//------------Initial Variable Settings-----------
	
	var newSquareAmount = 1
	var gridSize = 5;
	var squareSizePx = 800 / gridSize;
	//Map the objects position to their xy
	positions = []
	for(var i = 0; i <= (gridSize * 2); i++) {
		for(var j = 0; j <= i; j++) {
			if((i-j) < gridSize && j < gridSize) {
				positions.push({'x':(i-j),'y':j});
			}
		}
	}
	var curSquareCount = positions.length;
	theGrid = []
	//Create the objects
	for(var x = 0; x < curSquareCount; x++) {
		var newSquare = new Object()
		newSquare.elem = makeSquareDiv(x); //keep the DOM element
		theGrid.push(newSquare);
	}
	
	var buttons = new Object()
	buttons.countUpgrade = createCountUpgradeButton(0) //initial row
	buttons.countUpgrade.depth = 0
	
	function makeSquareDiv(index) {
		var div = document.createElement("div");
		div.style.width = squareSizePx + 'px'
		div.style.height = squareSizePx + 'px'
		div.style.top = positions[index].y * squareSizePx + 'px'
		div.style.left = positions[index].x * squareSizePx + 'px'
		div.style.background = 'black';
		div.setAttribute('class', 'gridSquare');
		document.getElementById('theGrid').appendChild(div);
		return div;
	}
	
	function setColorsForNewSquare(index, h, s, l, fadeTime) {
		theGrid[index].alive = 1;
		theGrid[index].h = h
		theGrid[index].s = s
		theGrid[index].l = l
		theGrid[index].fadeTimeMax = theGrid[index].fadeTimeLeft = fadeTime; // # of ticks
	}
	//------------------Formula----------------------
	function changeSquareColor(index) {
		var nextColor = 'black'
		if(theGrid[index].alive) {
			nextColor = getColorFromObj(theGrid[index])
		}
		theGrid[index].elem.style.background = nextColor;
	}
	
	function getColorFromObj(obj) { //h and l color fade time formula. returns hsl
		var h = obj.h
		var s = obj.s
		var l = obj.l
		if(obj.fadeTimeLeft) {
			h = h + (80 * obj.fadeTimeLeft / obj.fadeTimeMax)
			l = l - (25 * obj.fadeTimeLeft / obj.fadeTimeMax) - 8
		}
		return 'hsl('+h+','+s+'%,'+l+'%)'
	}
	
	//----------------Starting Point-----------------

	$scope.tick = function() {
		timer++
		timeList.push(new Date().getTime())
		if(timeList.length > 100) {
			timeList.splice(0, 1)

			//TODO instead of calc average, sub first from last / 2
			var fps = msWaitTime/calcAverageTime()*100
			multFromFps = 100/fps
			$scope.fps = round(fps)+"%"
		} else {
			multFromFps = 1
			$scope.fps = "..."
		}

		//ACTION here
		if(timer % 5 == 0) {
			for(var x = 0; x < newSquareAmount; x++) {
				addNewSquareOfType(0)
			}
		}
		
		//Check color, for the squares that need it
		for(var x = 0; x < theGrid.length; x++) {
			if(theGrid[x].fadeTimeLeft > 0) {
				theGrid[x].fadeTimeLeft--
				changeSquareColor(x)
			}
		}
	}
	
	
	function addNewSquareOfType(type) { //Fade & color formulas
		if(currentIndexOfDepth[type] >= curSquareCount) { //if done adding
			 if(theGrid[curSquareCount-1].fadeTimeLeft == type) { //if done fading in
				victoryForType(type)
			}
		} else {
			var color = 216 - type * 49
			var fadeTime = (30 + 30 * type * Math.pow(1.5, type) - fadeReduction)|0  // the |0 is Math.floor
			if(fadeTime < 0) {
				fadeTime = 0;
			}
			setColorsForNewSquare(currentIndexOfDepth[type], color, 51, 33, fadeTime) //intial s and l
			changeSquareColor(currentIndexOfDepth[type])
			currentIndexOfDepth[type]++
		}
	}
	
	function victoryForType(type) {
		// console.log('1 '+type +', '+ timer+', '+currentIndexOfDepth[type])
		if(currentIndexOfDepth[type+1] && currentIndexOfDepth[type+1] == curSquareCount && theGrid[currentIndexOfDepth[type]-1].fadeTimeLeft == 0) { //if the above layer is ready
			victoryForType(type+1)
			currentIndexOfDepth[type] = currentIndexOfDepth[type+1]
			return
		}
		if(currentIndexOfDepth[type+1] === undefined) {
			currentIndexOfDepth[type+1] = 0;
		}
		addNewSquareOfType(type+1)
		currentIndexOfDepth[type] = currentIndexOfDepth[type+1];
		// console.log('2 '+type +', '+ timer+', '+currentIndexOfDepth[type])
		clearGridFrom(currentIndexOfDepth[type], theGrid.length)
	}
	
	//--------------------Buttons--------------------
	function clickCountUpgradeButton() {
		var depth = buttons.countUpgrade.depth
		var i = findIndexOfGrid(0, buttons.countUpgrade.row)
		if(theGrid[i].alive == 1 && theGrid[i].fadeTimeLeft <= 0 && currentIndexOfDepth[depth] > i) {
			var newIndex = (currentIndexOfDepth[depth] - (i+1))
			if(currentIndexOfDepth[depth+1] && newIndex <= currentIndexOfDepth[depth+1]) {
				newIndex = currentIndexOfDepth[depth+1] //retreat to latest currency
			} else if(newIndex < 0) {
				newIndex = 0
			}
			clearGridFrom(newIndex, currentIndexOfDepth[depth])
			currentIndexOfDepth[depth] = newIndex
			
			buttons.countUpgrade.row+=2
			if(buttons.countUpgrade.row >= gridSize) {
				buttons.countUpgrade.row = 0
				buttons.countUpgrade.depth++
			}
			buttons.countUpgrade.style.top = buttons.countUpgrade.row * squareSizePx + 'px'
			buttons.countUpgrade.style.background = getColorFromObj({'h':216 - depth * 49,'s':51,'l':33})
			
			newSquareAmount++
			fadeReduction+=3*(depth+1)
		}
		else {
			//clicked w/o the money
			buttons.countUpgrade.style.border = '2px solid red'
		}
	}
	
	function clearGridFrom(index1, index2) {
		for(var x = index1; x < index2; x++) {
			theGrid[x].alive = 0;
			theGrid[x].fadeTimeLeft = 0;
			changeSquareColor(x)
		}
	}
	
	function createCountUpgradeButton(row) {
		var div = document.createElement("div");
		div.row = row;
		div.style.height = ((squareSizePx/3)|0) + 'px'
		div.style.width = squareSizePx + 'px'
		div.style.marginTop = ((squareSizePx/3)|0)+'px'
		div.style.background = getColorFromObj({'h':216,'s':51,'l':33})
		div.style.left = -(squareSizePx+10)+'px'
		div.style.top = row * squareSizePx + 'px'
		div.setAttribute('class', 'buyButton');
		div.onclick = clickCountUpgradeButton;
		div.style.border = '2px solid grey'
		div.onmouseover = function() {
			buttons.countUpgrade.style.background = getColorFromObj({'h':216 - buttons.countUpgrade.depth * 49,'s':51,'l':50})
		}
		div.onmouseout = function() {
			buttons.countUpgrade.style.background = getColorFromObj({'h':216 - buttons.countUpgrade.depth * 49,'s':51,'l':33})
			buttons.countUpgrade.style.border = '2px solid grey'
		}
		document.getElementById('theGrid').appendChild(div);
		return div;
	}
	
	function findIndexOfGrid(x, y) {
		for(var i = 0; i < positions.length; i++) {
			if(positions[i].x == x && positions[i].y == y) {
				return i;
			}
		}
	}
	function findXGivenRow(row) {
		for(var x = 0; x < positions.length; x++) {
			if(positions[x].x == 0 && positions[x].y == row) {
				return x;
			}
		}
	}
	

	{//--------------- Utility Functions----------------- AKA Not specific to this game
		$scope.toggleStartStop = function() {
			stop = !stop
			$scope.hoveredStartStopButton(true)
			timeList = []
		}
		
		$scope.hoveredStartStopButton = function(isEntering) {
			startStopButton = document.getElementById('startStop')
			if(isEntering) {
				if(!stop) {
					startStopButton.style.fill='#A71A1A';
				} else {
					startStopButton.style.fill='#44A248';
				}
			} else {
				if(!stop) {
					startStopButton.style.fill='#841414';
				} else {
					startStopButton.style.fill='#2E7932';
				}
			}
		}

		//because I hate IE so much
		Math.log2 = Math.log2 || function(x){return Math.log(x)*Math.LOG2E;};

		function calcAverageTime() {
			total = 0;
			for(x = 1; x < timeList.length; x++) {
				total += timeList[x] - timeList[x-1]
			}
			return total / (timeList.length-1)
		}

		function round3(num) {
			return Math.floor(num*1000)/1000
		}
		function round2(num) {
			return Math.floor(num*100)/100
		}
		function round1(num) {
			return Math.floor(num*10)/10
		}

		function round(num) {
			return formatNumber(num);
		} function formatNumber(num) {
			return Math.floor(num).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
		}

		/*
		  Converts an HSL color value to RGB. Conversion formula
		  adapted from http://en.wikipedia.org/wiki/HSL_color_space.
		  Assumes h, s, and l are contained in the set [0, 1] and
		  returns r, g, and b in the set [0, 255].

		  @param   Number  h       The hue
		  @param   Number  s       The saturation
		  @param   Number  l       The lightness
		  @return  Array           The RGB representation
		 */
		function hslToRgb(h, s, l){
			var r, g, b;

			if(s == 0){
				r = g = b = l; // achromatic
			}else{
				var hue2rgb = function hue2rgb(p, q, t){
					if(t < 0) t += 1;
					if(t > 1) t -= 1;
					if(t < 1/6) return p + (q - p) * 6 * t;
					if(t < 1/2) return q;
					if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
					return p;
				}

				var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
				var p = 2 * l - q;
				r = hue2rgb(p, q, h + 1/3);
				g = hue2rgb(p, q, h);
				b = hue2rgb(p, q, h - 1/3);
			}

			return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
		}

		/*
		  Converts an RGB color value to HSL. Conversion formula
		  adapted from http://en.wikipedia.org/wiki/HSL_color_space.
		  Assumes r, g, and b are contained in the set [0, 255] and
		  returns h, s, and l in the set [0, 1].

		  @param   Number  r       The red color value
		  @param   Number  g       The green color value
		  @param   Number  b       The blue color value
		  @return  Array           The HSL representation
		 */
		function rgbToHsl(r, g, b){
			r /= 255, g /= 255, b /= 255;
			var max = Math.max(r, g, b), min = Math.min(r, g, b);
			var h, s, l = (max + min) / 2;

			if(max == min){
				h = s = 0; // achromatic
			}else{
				var d = max - min;
				s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
				switch(max){
					case r: h = (g - b) / d + (g < b ? 6 : 0); break;
					case g: h = (b - r) / d + 2; break;
					case b: h = (r - g) / d + 4; break;
				}
				h /= 6;
			}

			return [h, s, l];
		}

		//ang helper methods
		$scope.buyButtonClicked = function(costVar, resultOfFinish) {
			if($scope.theResource >= costVar) {
				$scope.theResource -= costVar //cost
				resultOfFinish()
			}
		}
		


	}


	{//----The Timer----
	//this way doesn't work when javascript is open in a different tab
	//javascript will default change the 5 to minimum 500 in that case
	//use interval.js somehow to get around it. google that along with angular?
	msWaitTime = 50 //doesn't actually wait decimal amounts
	$interval(function() { if(!stop) $scope.tick(); }, msWaitTime);
	}
});
</script>
